/*
 * =====================================================================================
 *
 *       Filename:  download_file.h
 *
 *    Description:  download stream meidia file
 *
 *        Version:  1.0
 *        Created:  03/19/2015 03:07:25 PM
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Sun Jun (), mindfulstart@gmail.com
 *   Organization:  
 *
 * =====================================================================================
 */

#ifndef  DOWNLOAD_FILE_INC
#define  DOWNLOAD_FILE_INC

#define MAX_STREAM_COUNT  15
#define PACKET_SIZE     3000

#include <pthread.h>
#include <stdio.h>
#include <libavformat/avformat.h>


enum Download_status {
    DOWNLOAD_STOP,
    DOWNLOAD_START,
    DOWNLOAD_PAUSE,
};				/* ----------  end of enum DOWNLOAD_STATUS  ---------- */

typedef enum Download_status Download_status;

enum download_type {
    DOWNLOAD_DEFAULT,
    DOWNLOAD_PACKET_TEMP,
};				/* ----------  end of enum download_type  ---------- */

typedef enum download_type Download_type;

struct packet_data {
    int64_t pts;
    int64_t dts;
    int64_t pos;
    int stream_index;
};				/* ----------  end of struct packet_data  ---------- */


struct CMPCore
{
   AVFormatContext *avf_ctx;
   _Bool is_opened;
   _Bool has_download_stopped;
   _Bool exit;
    
};

typedef struct CMPCore CMPCoreData;

typedef struct packet_data Packet_data;

struct download_context {
    char *network_url;
    char *local_file_path;
    char *local_packet_file_path;
    int need_write_packet;

    int readed_packet_nb;
    int writed_packet_nb;

    Packet_data *packet_array;
    int cur_file_pos;
    int packet_array_size;
    int packet_start_time;
    int64_t packet_end_time;

    int writed_to_eof;

    int streaming_duration;

    int start_download_time;//(play)time start to download.
    int64_t last_dts;// last dts downloaded to.
    int64_t skip_bytes;// skip bytes to write.Overwrite if it is 0.
    int64_t current_dts;
    int64_t current_bytes;
    long timestamp;
    int timeout;
//    int is_input_opened;///open_input()被打断的话，会引起invalid data..进而connection refuse，得重启服务器才正常
    int buffer_type_restart;

    int is_live;

    int has_pkt_file_removed;

    pthread_mutex_t *mutex;
    pthread_cond_t *cond;
    pthread_t download_tid;

    Download_status status;
    Download_type type;

    AVFormatContext *ifmt_ctx;

    FILE *packet_file_read;
    FILE *packet_file_write;

	void (*on_download_progress_changed)(int64_t pos, int64_t dts, int current_time, int download_type);//pts_array[],int stream_num,
	void (*on_download_finished)();
	void (*on_download_failed)(char* msg);
	void (*set_start_time)(int startTime);
	void (*write_exist_finished)();
	void (*on_buffering)();
};				/* ----------  end of struct download_file  ---------- */

typedef struct download_context Download_context;

Download_context *init_download(const char *file_url, const char *file_path, const char *file_packet);
void deinit_download(Download_context *download_ctx);
int start_download(Download_context *download_ctx);
void stop_temp_download();
void stop_temp_download_thread();
void set_download_status(Download_context *download_ctx, Download_status status);
Download_status get_download_status(Download_context *download_ctx);
int get_duration(Download_context *download_ctx);
void start_temp_download_thread(char *input_path, char *pkt_path, int64_t start_pos, int timeout, int is_restart);

size_t read_packet_from_file(AVPacket *packet, Download_context *d_ctx);

int seek_packet_file(Download_context *download_ctx_ori, int64_t seek_target, int stream_index);
#endif   /* ----- #ifndef DOWNLOAD_FILE_INC  ----- */
